# -*- coding: utf-8 -*-
from openerp.osv import fields
from openerp.osv import osv
from openerp import api, models
from openerp import fields as fields_new
from openerp.tools.translate import _
from datetime import datetime
import openerp.addons.decimal_precision as dp
from openerp.tools import float_compare, float_round

ISODATEFORMAT = '%Y-%m-%d'
ISODATETIMEFORMAT = "%Y-%m-%d %H:%M:%S"


class sale_order(osv.osv):
    _inherit = 'sale.order'
    _columns = {
        'sale_order_invoice': fields.many2one('official.invoice', string=u'纸质发票信息', copy=False),
    }


class official_invoice(osv.osv):
    _name = 'official.invoice'

    _rec_name = 'id'

    def return_money_is_checked(self, cr, uid, ids, context=None):
        for official_invoice_obj in self.browse(cr, uid, ids, context=context):
            official_invoice_obj.write({'is_checked': True})
        return True

    def _compute_invoice_amount_total(self, cr, uid, ids, name, arg, context=None):
        # 实时计算已开票的 金额 以及    差额字段
        res = {}
        for official_invoice in self.pool.get('official.invoice').browse(cr, uid, ids, context=context):
            invoice_money = 0
            for official_lines in official_invoice.official_lines_ids:
                invoice_money += official_lines.invoice_money
            res[official_invoice.id] = {'invoice_amount_total': invoice_money,
                                        'balance': invoice_money - official_invoice.sale_order_amount_total - official_invoice.return_money - official_invoice.tax}

        return res

    def all_is_invoiced(self, cr, uid, ids, context=None):
        # 财务页面上 发票 已开按钮对应的方法 目标是 点击按钮后 所有的纸质发票行的 是否已开为True
        for official_invoice in self.browse(cr, uid, ids, context=context):
            for official_line in official_invoice.official_lines_ids:
                if not official_line.is_invoiced:
                    official_line.write(
                        {"is_invoiced": True, 'make_invoice_date': (datetime.now()).strftime(ISODATETIMEFORMAT)})
        return True

    def unlink(self, cr, uid, ids, context=None):
        # 如果有部分行的发票已经开过了，就不允许删除整张纸质发票申请
        for sale_invoice in self.browse(cr, uid, ids, context=context):
            for sale_invoice_line in sale_invoice.official_lines_ids:
                if sale_invoice_line.is_invoiced:
                    raise osv.except_osv(_('Warning!'),
                                         u'客户%s销售订单纸质发票部分已开，不能删除！' % (sale_invoice.partner_id.name))
        super(official_invoice, self).unlink(cr, uid, ids, context=context)
        return True

    def write(self, cr, uid, ids, vals, context=None):
        return_vals = super(official_invoice, self).write(cr, uid, ids, vals, context=context)
        for official_invoice_objs in self.browse(cr, uid, ids, context=context):
            invoice_money = sum([line_objs.invoice_money for line_objs in official_invoice_objs.official_lines_ids])
            sale_order_amount_total = sum(
                [sale_objs.amount_total for sale_objs in official_invoice_objs.sale_order_ids])
            if float_compare(invoice_money - sale_order_amount_total - official_invoice_objs.return_money,
                             official_invoice_objs.tax, 2) < 0:
                raise osv.except_osv(u'错误', u'开票金额不足或返还过多，如果开票金额不足需要添加一条余额开票记录并打勾不开票。')
        return return_vals

    def fields_view_get(self, cr, uid, view_id=None, view_type='form',
                        context=None, toolbar=False, submenu=False):
        # 当选取销售订单然后 生成 纸质发票的时候 就检查一些条件
        # 1.销售订单已取消，不允许申请纸质发票
        # 2.销售订单已有发票申请'
        # 3.不同的客户不能，同时生成纸质发票申请'
        # 4.次只能为一个销售员进行请纸，请核对后再进行操作
        if context is None:
            context = {}
        res = super(official_invoice, self).fields_view_get(
            cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=False)
        if context.get('active_model', '') == 'sale.order' and len(context['active_ids']) >= 1 and context.get(
                "no_judge", True):
            list_partner, list_user = [], []
            for sale_order in self.pool.get('sale.order').browse(cr, uid, context['active_ids'], context=context):

                if sale_order.state == 'cancel':
                    raise osv.except_osv(u'错误', u'销售订单已取消，不允许申请纸质发票！')

                list_partner.append(sale_order.partner_id.id)
                # list_user.append(sale_order.user_id.id)
                all_record = set(self.search(
                    cr, uid, [('sale_order_ids', 'in', [sale_order.id])], context=context))
                if len(all_record) >= 1:
                    raise osv.except_osv(_('Warning!'),
                                         u'%s销售订单已有发票申请' % (sale_order.name))
            if len(set(list_partner)) != 1:
                raise osv.except_osv(_('Warning!'),
                                     u'不同的客户不能，同时生成纸质发票申请')
        return res

    def create_official_invoice(self, cr, uid, ids, context=None):
        # 这个方法就是为了返回 新生成的纸质发票申请的页面， 并且进行检查，和数据的回写。
        # 从这个方法里明白了一个道理， 就是在odoo系统里面 在在编辑状态 点击页面上的按钮的时候其实这个记录已经保存在数据库里面了。

        for sale_invoice in self.browse(cr, uid, ids, context=context):
            if sale_invoice.balance < 0:
                raise osv.except_osv(u'错误', u'开票金额不足或返还过多，如果开票金额不足需要添加一条余额开票记录并打勾不开票。')
            # 574 当is_no_return打勾时用余额填充no_return_money值，去除勾时no_return_money清0
            if sale_invoice.is_no_return:
                self.write(cr, uid, ids, {
                    'no_return_money': sale_invoice.invoice_amount_total - sale_invoice.sale_order_amount_total -
                                       sale_invoice.return_money - sale_invoice.tax - sale_invoice.no_return_money},
                           context=context)
            if not sale_invoice.is_no_return:
                self.write(cr, uid, ids, {'no_return_money': 0}, context=context)

        mod_obj = self.pool.get('ir.model.data')
        act_obj = self.pool.get('ir.actions.act_window')
        result = mod_obj.get_object_reference(
            cr, uid, 'hfsy_ext', 'sale_order_invoice_action')
        id = result and result[1] or False
        context.update({"no_judge": False})
        result = act_obj.read(cr, uid, [id], context=context)[0]
        res = mod_obj.get_object_reference(
            cr, uid, 'hfsy_ext', 'official_invoice_form_sale')
        result['views'] = [(res and res[1] or False, 'form')]
        result['res_id'] = ids[0]
        return result

    def set_defalult_line_val(self, cr, uid, context=None):
        # 新建的时候设置 纸质发票申请的行的 默认值
        return [[0, False, {'invoice_title': (
            self.pool.get('sale.order').browse(cr, uid, context.get('active_ids')[0])).partner_id.name,
                            'invoice_money': sum([sale_order.amount_total for sale_order in
                                                  self.pool.get('sale.order').browse(cr, uid, context.get('active_ids'),
                                                                                     context=context)]),
                            'invoice_corp': (self.pool.get('sale.order').browse(cr, uid, context.get('active_ids')[
                                0])).user_id.company_id.name}]]

    def _get_sale_order_official_invoice(self, cr, uid, ids, context=None):
        order_id = {}
        for sale_order in self.pool.get('sale.order').browse(cr, uid, ids, context=context):
            if sale_order.sale_order_invoice.id:
                order_id[sale_order.sale_order_invoice.id] = True
        return order_id.keys()

    def _compute_sale_order_amount_total(self, cr, uid, ids, name, arg, context=None):
        # 计算销售订单的 本次申请的 所有的金额
        res = {}
        for official_invoice in self.pool.get('official.invoice').browse(cr, uid, ids, context=context):
            invoice_money = 0
            for sale_order in self.pool.get('sale.order').browse(cr, uid, [order_id.id for order_id in
                                                                           official_invoice.sale_order_ids],
                                                                 context=context):
                invoice_money += sale_order.amount_total
            res[official_invoice.id] = invoice_money
        return res

    def _get_sale_order_official_invoice_ok(self, cr, uid, ids, context=None):
        # 计算销售总金额的 条件
        res = {}
        for official_invoice in self.pool.get('official.invoice').browse(cr, uid, ids, context=context):
            res[official_invoice.id] = True
        return res.keys()

    def get_sale_order_line(self, cr, uid, context=None):
        product_dict = {}
        product_messege_list = []
        active_ids = context.get('active_ids')
        if active_ids:
            for sale_order in self.pool.get('sale.order').browse(cr, uid, active_ids, context=context):
                for order_line in sale_order.order_line:
                    if order_line.product_id.name in product_dict:
                        product_dict[order_line.product_id.name] = [
                            product_dict[order_line.product_id.name][0] + order_line.product_uom_qty,
                            product_dict[order_line.product_id.name][1] + order_line.price_subtotal,
                            order_line.price_unit]
                    else:
                        product_dict[order_line.product_id.name] = [order_line.product_uom_qty,
                                                                    order_line.price_subtotal, order_line.price_unit]
            product_messege_list.append(
                u"<table class='table table-striped'><tr><td>产品</td><td>单价</td><td>数量</td><td>小计</td></tr>")

        for prodcut_name, qty in product_dict.items():
            product_messege_list.append(u"<tr> <td> %s </td> <td> %s </td><td> %s </td> <td> %s </td></tr>" % (
                prodcut_name, str(qty[2]), str(qty[0]), str(qty[1])))
        product_messege_list.append("</table>")
        return ''.join(product_messege_list)

    def _compute_is_all_invoiced(self, cr, uid, ids, name, arg, context=None):
        # 计算是否纸质发票申请的票 已经 全部开票
        res = {}
        for official_invoice in self.pool.get('official.invoice').browse(cr, uid, ids, context=context):
            is_invoiced = True
            for official_invoice_line in official_invoice.official_lines_ids:
                if not official_invoice_line.is_invoiced:
                    is_invoiced = False
            res[official_invoice.id] = is_invoiced
        return res

    def _get_is_all_invoiced(self, cr, uid, ids, context=None):
        # is_invoiced 是否开票字段 变化了 条件
        res = {}
        for official_invoice_line in self.pool.get('official.invoice.lines').browse(cr, uid, ids, context=context):
            res[official_invoice_line.official_invoice_id.id] = True
        return res.keys()

    def onchange_is_return_paid(self, cr, uid, ids, is_return_paid, context=None):
        if is_return_paid:
            return {'value': {'return_paid_date': (datetime.now()).strftime(ISODATEFORMAT)}}
        else:
            return {'value': {'return_paid_date': ''}}

    def onchange_return_paid_date(self, cr, uid, ids, return_paid_date, context=None):
        if return_paid_date:
            return {'value': {'is_return_paid': True}}
        else:
            return {'value': {'is_return_paid': False}}

    _columns = {
        'partner_id': fields.many2one('res.partner', string=u'客户'),
        'user_id': fields.many2one('res.users', string=u'销售员'),
        'sale_order_ids': fields.one2many('sale.order', 'sale_order_invoice', string=u'销售订单列表'),
        'sale_order_amount_total': fields.function(_compute_sale_order_amount_total, type='float', string=u'销售订单金额',
                                                   store={
                                                       'official.invoice': (
                                                           _get_sale_order_official_invoice_ok, ['sale_order_ids'], 15),
                                                       'sale.order': (_get_sale_order_official_invoice,
                                                                      ['order_line', 'sale_order_invoice'], 15),
                                                   }),
        'invoice_amount_total': fields.function(_compute_invoice_amount_total, type='float', string=u'开发票金额',
                                                multi='invoice_amount_total',
                                                store={
                                                    'official.invoice': (lambda self, cr, uid, ids, c={}: ids,
                                                                         ['official_lines_ids', 'sale_order_ids'], 20),
                                                }),
        # 'system_invoice_ids': fields.one2many(u'系统发票列表(预留，暂时不实现）'),self
        'official_lines_ids': fields.one2many('official.invoice.lines', 'official_invoice_id', string=u'销售订单列表'),
        'entry_item_memo': fields.text(u'进项备注'),
        'balance': fields.function(_compute_invoice_amount_total, string=u'差额', type='float',
                                   multi='invoice_amount_total',
                                   store={
                                       'official.invoice': (
                                           lambda self, cr, uid, ids, c={}: ids,
                                           ['official_lines_ids', 'sale_order_ids'],
                                           20),
                                       'sale.order': (
                                           _get_sale_order_official_invoice, ['order_line', 'sale_order_invoice'], 20),
                                   }),
        'return_money': fields.float(u'返回金额'),
        'apply_date_time': fields.datetime(u'申请日期'),
        'tax': fields.float(u'扣税'),
        'invoice_title': fields.related('official_lines_ids', 'invoice_title', type='char', string=u'发票抬头',
                                        readonly="1"),
        'invoice_corp': fields.related('official_lines_ids', 'invoice_corp', type='char', string=u'开票公司', readonly="1"),
        'sale_order_line': fields.html(string=u'销售订单行', readonly=False),
        'invoice_money': fields.related('official_lines_ids', 'invoice_money', type='float', string=u'开票金额',
                                        readonly="1"),
        'is_return_paid': fields.boolean(u'已返还'),
        'return_paid_date': fields.date(u'返还日期'),
        'is_no_return': fields.boolean(u'不返还'),
        'no_return_money': fields.float(u'不返还金额'),
        'is_all_invoiced': fields.function(_compute_is_all_invoiced, string=u'已经全部开票', type='boolean', store={
            'official.invoice.lines': (_get_is_all_invoiced, ['is_invoiced'], 20),
        }),
        'is_checked': fields.boolean(u'差额已审核')
    }
    _defaults = {
        # 因为这个会以wizard的形式 表现出来 所以很多字段都是需要默认值的呀 。。
        'sale_order_amount_total': lambda s, cr, uid, ctx={}: sum([sale_order.amount_total for sale_order in
                                                                   s.pool.get('sale.order').browse(cr, uid, ctx.get(
                                                                       'active_ids'), context=ctx)]),
        'user_id': lambda s, cr, uid, ctx={}: (
            s.pool.get('sale.order').browse(cr, uid, ctx.get('active_ids')[0])).user_id.id,
        'partner_id': lambda s, cr, uid, ctx={}: (
            s.pool.get('sale.order').browse(cr, uid, ctx.get('active_ids')[0])).partner_id.id,
        'sale_order_ids': lambda s, cr, uid, ctx={}: ctx.get('active_ids'),
        'official_lines_ids': set_defalult_line_val,
        'apply_date_time': lambda s, cr, uid, ctx={}: (datetime.now()).strftime(ISODATETIMEFORMAT),
        'no_return_money': 0,
        'sale_order_line': get_sale_order_line,
    }


class official_invoice_lines(osv.osv):
    _name = 'official.invoice.lines'
    _rec_name = 'official_invoice_id'

    def on_change_is_invoiced(self, cr, uid, ids, is_invoiced, receive_invoice_date, context=None):
        # 勾选了是否开票直接填充，开票日期。 如果没有勾选已开票，就把日期设置为空
        receive_time = None
        if not receive_invoice_date:
            if is_invoiced:
                receive_time = (datetime.now()).strftime(ISODATETIMEFORMAT)
            return {'value': {'receive_invoice_date': receive_time}}
        elif not is_invoiced:
            return {'value': {'receive_invoice_date': None}}

    def on_change_receive_invoice_date(self, cr, uid, ids, is_invoiced, receive_invoice_date, context=None):
        # 填写了，开票日期的选项就 自动勾选已开票的选项 ，如果清空开票日期，就把已开票的 选项，删除。
        if not is_invoiced and receive_invoice_date:
            return {'value': {'receive_invoice_date': receive_invoice_date, 'is_invoiced': True}}
        elif not receive_invoice_date:
            return {'value': {'is_invoiced': False}}

    def on_change_supplier_select(self, cr, uid, ids, supplier_select, context=None):
        if supplier_select:
            partner_objs = self.pool.get('res.partner').browse(cr, uid, supplier_select, context=context)
            return {'value': {'invoice_corp': partner_objs[0].name}}

    def create(self, cr, uid, vals, context=None):
        # 如果点击不开发票的选项，就直接把一些公司 抬头之类的信息进行清空
        if vals.get("is_no_invoice", False):
            vals.update({'invoice_title': '', 'invoice_content': '', 'invoice_corp': '',
                         'make_invoice_date': None, 'invoice_memo': ''})
        return super(official_invoice_lines, self).create(
            cr, uid, vals, context=context)

    def write(self, cr, uid, ids, vals, context=None):
        # 如果点击不开发票的选项，就直接把一些公司 抬头之类的信息进行清空
        if vals.get("is_no_invoice", False):
            vals.update({'invoice_title': '', 'invoice_content': '', 'invoice_corp': '',
                         'make_invoice_date': None, 'invoice_memo': ''})
        if vals.get('is_invoiced'):
            for invoice_row in self.browse(cr, uid, ids, context=context):
                if invoice_row.official_invoice_id and not invoice_row.official_invoice_id.is_checked \
                        and invoice_row.official_invoice_id.sale_order_ids:
                    raise osv.except_osv(_('Warning!'),
                                         u'差额还未审核，不能开发票！')
        return super(official_invoice_lines, self).write(
            cr, uid, ids, vals, context=context)

    # 取得关联的系统发票的某核销account_move_line的分录名称
    def _compute_reconcile_account_name(self, cr, uid, ids, name, arg, context=None):
        res = {}
        if ids:
            for official_invoice_line in self.pool['official.invoice.lines'].browse(cr, uid, ids, context=context):
                payment_ids = official_invoice_line.system_invoice_id.payment_ids
                if payment_ids:
                    payment_id = payment_ids[0].id
                    move_line = self.pool['account.move.line'].browse(cr, uid, payment_id, context=context)
                    res[official_invoice_line.id] = {"reconcile_account_name": move_line.journal_id.name,
                                                     "reconcile_time": (datetime.now()).strftime(ISODATEFORMAT)}
        return res

    # 取得核销的凭证行对应的系统发票的“纸质发票id”和“凭证行的分录名称”对应关系
    def _get_account_invoice_payment_ids(self, cr, uid, ids, context=None):
        res = {}
        for line_row in self.pool['account.move.line'].browse(cr, uid, ids, context=context):
            move_id = line_row.move_id.id
            for invoice_id in self.pool['account.invoice'].search(cr, uid, [('move_id', '=', move_id)],
                                                                  context=context):
                official_invoice_lines_ids = self.pool['official.invoice.lines']. \
                    search(cr, uid, [('system_invoice_id', '=', invoice_id)], context=context)
                for official_invoice_line_id in official_invoice_lines_ids:
                    res[official_invoice_line_id] = line_row.journal_id.name
        return res

    def ticketed_is_invoiced(self, cr, uid, ids, context=None):
        for line in self.browse(cr, uid, ids, context=context):
            line.write({'is_invoiced': True})
        return True

    def report_vendor(self, cr, uid, ids, context=None):
        for line in self.browse(cr, uid, ids, context=context):
            line.write({'is_sent_supplier': True})
        return True

    def report_is_returned_money(self, cr, uid, ids, context=None):
        for line in self.browse(cr, uid, ids, context=context):
            line.write({'is_returned_money': True})
        return True

    _columns = {
        'invoice_title': fields.char(u'发票台头'),
        'invoice_content': fields.char(u'发票内容'),
        'invoice_money': fields.float(u'开票金额'),
        'invoice_corp': fields.char(u'开票公司名称'),
        'supplier_select': fields.many2one('res.partner', domain="[('supplier','=',True)]", string=u'供应商选择'),
        'make_invoice_date': fields.datetime(u'发票日期', ),
        'invoice_code': fields.char(u'发票号码'),
        'is_invoiced': fields.boolean(u'是否已开'),
        'invoice_memo': fields.char(u'发票备注'),
        'official_invoice_id': fields.many2one('official.invoice', string=u'主发票id'),
        'is_no_invoice': fields.boolean(u'不开票'),
        'receive_invoice_date': fields.datetime(u'收到发票时间'),
        'partner_id': fields.related('official_invoice_id', 'partner_id', type='many2one', relation='res.partner',
                                     string=u'客户', store=True, readonly="1"),
        'user_id': fields.related('official_invoice_id', 'user_id', type='many2one', relation='res.users', string=u'销售员',
                                  store=True, readonly="1"),
        'is_outer_invoice': fields.boolean(u'外部开票'),
        'reconcile_time': fields.date(string=u"核销时间"),
        'balance_notes': fields.char(u'差额备注（高开原因）'),
        'invoice_type': fields.selection([(u'增值税专用发票', u'增值税专用发票'),
                                          (u'增值税普通发票', u'增值税普通发票')], string=u'发票类型'),
        'is_sent_supplier': fields.boolean(u'是否上报供应商'),
        'is_client_paid': fields.boolean(u'是否已转账'),
        'is_returned_money': fields.boolean(u'是否已回款'),
        'pay_method': fields.selection([(u'转账', u'转账'), (u'现金', u'现金'), (u'支票', u'支票'), (u'POS机', u'POS机')],
                                       string=u'付款方式'),
        'sale_order_ids': fields.related('official_invoice_id', 'sale_order_ids', type='one2many',
                                         relation='sale.order', string=u'销售订单'),
    }
    _defaults = {
        "is_invoiced": False,
    }


class change_official_invoice_sale_wizard(osv.osv_memory):
    _name = 'change.official.invoice.sale.wizard'

    def _set_default_sale(self, cr, uid, context=None):
        message_list = []
        for official_invoice_objs in self.pool.get('official.invoice').browse(cr, uid, context.get('active_id'),
                                                                              context=context):
            for sale_order_objs in official_invoice_objs.sale_order_ids:
                message_list.append([0, False,
                                     {'sale_id': sale_order_objs.id, 'partner_id': sale_order_objs.partner_id.id,
                                      'amount_total': sale_order_objs.amount_total}])
        return message_list

    def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
        if context is None:
            context = {}
        res = super(change_official_invoice_sale_wizard, self).fields_view_get(
            cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=False)
        if context.get('active_model', '') == 'official.invoice':
            for official_invoice_objs in self.pool.get('official.invoice').browse(cr, uid, context['active_ids'],
                                                                                  context=context):
                if official_invoice_objs.is_checked:
                    raise osv.except_osv(_('Warning!'),
                                         u'纸质发票的返还金额已经审核,不能修改!\n '
                                         u'如要修改请联系会计取消审核后在操作!')
        return res

    def change_official_invoice_sale(self, cr, uid, ids, context=None):
        change_sale_wizard_objs = self.browse(cr, uid, ids, context=context)[0]
        sale_order_objs_list = []
        for official_invoice_sale_wizard_objs in change_sale_wizard_objs.official_invoice_sale_wizard_ids:
            sale_order_objs_list.append(official_invoice_sale_wizard_objs.sale_id)
        old_sale_order_list = [sale_order_objs for sale_order_objs in
                               change_sale_wizard_objs.official_invoice_id.sale_order_ids]
        sale_order_objs_list = list(set(sale_order_objs_list))
        sale_order_amount_total = sum([sale_objs.amount_total for sale_objs in sale_order_objs_list])
        sale_order_add_list, delete_list = list(set(sale_order_objs_list) - set(old_sale_order_list)), list(
            set(old_sale_order_list) - set(sale_order_objs_list))
        vals = {'official_lines_ids': [], 'sale_order_ids': [], 'sale_order_line': ''}

        context.update({'active_ids': [sale_objs.id for sale_objs in sale_order_objs_list]})
        message = self.pool.get('official.invoice').get_sale_order_line(cr, uid, context=context)
        if sale_order_add_list:
            vals = {'official_lines_ids': [[0, False, {
                'official_invoice_id': change_sale_wizard_objs.official_invoice_id.id,
                'invoice_money': sale_order_amount_total - change_sale_wizard_objs.official_invoice_id.invoice_amount_total,
                'invoice_corp': sale_order_objs_list[0].user_id.company_id.name,
                'partner_id': sale_order_objs_list[0].partner_id.id}]]}

            vals.update({'invoice_amount_total': sale_order_amount_total})
        vals.update(
            {'sale_order_ids': [[6, False, [sale_order_objs.id for sale_order_objs in sale_order_objs_list]]]})
        vals.update({'sale_order_line': message})
        change_sale_wizard_objs.official_invoice_id.write(vals)
        return True

    _columns = {
        'official_invoice_sale_wizard_ids': fields.one2many('official.invoice.sale.wizard.line',
                                                            'official_invoice_sale_id', string='销售订单列表'),
        'partner_id': fields.many2one('res.partner'),
        'official_invoice_id': fields.many2one('official.invoice'),
    }
    _defaults = {
        'official_invoice_sale_wizard_ids': _set_default_sale,
        'partner_id': lambda self, cr, uid, context=None: (
            self.pool.get('official.invoice').browse(cr, uid, context.get('active_id'), context=context)
            and (self.pool.get('official.invoice').browse(cr, uid, context.get('active_id'), context=context)
                 )[0].partner_id.id),
        'official_invoice_id': lambda s, c, u, ctx=None: ctx.get('active_id')
    }

class official_invoice_sale_wizard_line(osv.osv_memory):
    _name = 'official.invoice.sale.wizard.line'
    _columns = {
        'official_invoice_sale_id': fields.many2one('change.official.invoice.sale.wizard'),
        'sale_id': fields.many2one('sale.order', u'销售订单', required=True),
        'partner_id': fields.many2one('res.partner', u'客户'),
        'amount_total': fields.float(u'销售订单金额'),
    }

    def on_change_sale_order_id(self, cr, uid, ids, sale_id, context=None):
        sale_order_objs = self.pool.get('sale.order').browse(cr, uid, sale_id, context=context)
        return_vals = {
            'value': {'partner_id': sale_order_objs.partner_id.id, 'amount_total': sale_order_objs.amount_total}}
        return return_vals
